// 中断基址
#define INT_BASE    (0xca000000)
// 中断屏蔽器
#define INT_MASK    (INT_BASE + 0x8)
// timer4的偏移值
#define INTOFFSET   (INT_BASE + 0x14)
// 通过屏蔽的中断寄存器
#define INTPND      (INT_BASE + 0x10)
// 主中断源寄存器,标识哪个硬件产生了中断
#define SRCPND      (INT_BASE + 0x0)
 
extern void printk(char *fmt,...);
// 中断公共处理函数
void common_irq_handler(void)
{
    unsigned int tmp = (1 << (*(volatile unsigned int *)INTOFFSET));
    printk("%d\n",*(volatile unsigned int *)INTOFFSET);
    *(volatile unsigned int *)SRCPND |= tmp;
    *(volatile unsigned int *)INTPND |= tmp;
    printk("timer alarming\n");
}
 
// 定时器基址
#define TIMER_BASE      (0xd1000000)
// 一级分频器
#define TCFG0           ((volatile unsigned int *)(TIMER_BASE + 0x0))
// 二级分频器
#define TCFG1           ((volatile unsigned int *)(TIMER_BASE + 0x4))
// 定时控制器
#define TCON            ((volatile unsigned int *)(TIMER_BASE + 0x8))
// timer4减数器
#define TCONB4          ((volatile unsigned int *)(TIMER_BASE + 0x3c))
 
// 使能中断
void enable_irq(void)
{
    asm volatile
    (
        "mrs r4,cpsr\t\n"
        "bic r4,r4,#0x80\t\n"
        "msr cpsr,r4\t\n"
        :
        :
        :"r4"
    );
}
 
// 失能中断
void disable_irq(void)
{
	asm volatile 
    (
		"mrs r4,cpsr\n\t"
		"orr r4,r4,#0x80\n\t"
		"msr cpsr,r4\n\t"
		:
        :
        :"r4"
	);
}
 
// 失能某个中断屏蔽位
void umask_int(unsigned int offset)
{
    *(volatile unsigned int *)INT_MASK &= ~(1 << offset);
}
 
// 定时器初始化
void timer_init(void)
{
	*TCFG0 |= 0x800;
	*TCON &= (~(7<<20));
	*TCON |= (1<<22);
	*TCON |= (1<<21);
 
	*TCONB4 = 10000;
 
	*TCON |= (1<<20);
	*TCON &= ~(1<<21);
 
	umask_int(14);
	enable_irq();
}